package com.ciwong.epaper.application;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.util.Log;

import com.baidu.ocr.sdk.OCR;
import com.baidu.ocr.sdk.OnResultListener;
import com.baidu.ocr.sdk.exception.OCRError;
import com.baidu.ocr.sdk.model.AccessToken;
import com.ciwong.ciwongwrite.CWApplication;
import com.ciwong.epaper.bean.CheckFloatPermissionBean;
import com.ciwong.epaper.bean.UserAccountInfo;
import com.ciwong.epaper.modules.bookstore.dao.BookstoreAction;
import com.ciwong.epaper.modules.cordva.dao.CordvaAction;
import com.ciwong.epaper.modules.dictation.dao.DictationAction;
import com.ciwong.epaper.modules.epaper.bean.EpaperInfo;
import com.ciwong.epaper.modules.epaper.bean.Grade;
import com.ciwong.epaper.modules.epaper.dao.EpaperAction;
import com.ciwong.epaper.modules.epaper.dao.EpaperDao;
import com.ciwong.epaper.modules.epaper.lsdao.LSAction;
import com.ciwong.epaper.modules.epaper.util.AppFrontBackHelper;
import com.ciwong.epaper.modules.epaper.util.EpaperSys;
import com.ciwong.epaper.modules.me.bean.Clazz;
import com.ciwong.epaper.modules.me.bean.SchoolDetail;
import com.ciwong.epaper.modules.me.bean.ServiceDetail;
import com.ciwong.epaper.modules.me.dao.MeAction;
import com.ciwong.epaper.modules.me.dao.db.db.StudyRecordDB;
import com.ciwong.epaper.modules.msg.dao.MsgAction;
import com.ciwong.epaper.modules.reciteWords.dao.WordAction;
import com.ciwong.epaper.modules.reciteWords.util.download.BaseDownLoad;
import com.ciwong.epaper.modules.scan.dao.ScanAction;
import com.ciwong.epaper.modules.wordlist.dao.WorkBookAction;
import com.ciwong.epaper.service.UploadeFailService;
import com.ciwong.epaper.util.AESCBCUtil;
import com.ciwong.epaper.util.ALiYunManager;
import com.ciwong.epaper.util.EConstants;
import com.ciwong.epaper.util.ESystem;
import com.ciwong.epaper.util.FeedbackUtil;
import com.ciwong.epaper.util.FileUtil;
import com.ciwong.epaper.util.IntentFlag;
import com.ciwong.epaper.util.SerializableManager;
import com.ciwong.epaper.util.download.DownLoad;
import com.ciwong.epaper.util.download.DownLoadDB;
import com.ciwong.epaper.utils.Constants;
import com.ciwong.eventbus.EventBus;
import com.ciwong.libs.utils.CWSys;
import com.ciwong.libs.utils.volley.BaseRequest;
import com.ciwong.libs.utils.volley.HttpRequest;
import com.ciwong.mobilelib.application.BaseApplication;
import com.ciwong.mobilelib.application.CWCrashHandler;
import com.ciwong.mobilelib.eyeguard.EyeGuardModeView;
import com.ciwong.mobilelib.i.BaseCallBack;
import com.ciwong.mobilelib.utils.BaseConstants;
import com.ciwong.mobilelib.utils.StatUtils;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.stetho.Stetho;
import com.liulishuo.filedownloader.FileDownloader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.GINGERBREAD;

/**
 * 电子报 Application
 *
 * @author bin
 * @version ciwong v.1.0 2015/7/23 20:13
 * @since ciwong v.1.0
 */
public class EApplication extends CWApplication {

    private boolean hasGotToken = false;
    private String hasGotTokenMessage = "";
    public static final boolean isSymbolColoration = true;
    public static final boolean isIngnorAccent = true;

    private static final String TAG = "EApplication";
    /**
     * 单例模式
     */
    private static EApplication instance;

    /**
     * 品牌ID
     */
    public static int BRAND_ID;
    /**
     * 用于升级用
     */
    public static int OLD_BRAND_ID;
    /**
     * 微信支付应用类型ID
     */
    public static int TYPE_ID;

    /**
     * 服务详情列表
     */
    private List<ServiceDetail> mServiceDetails;

    /**
     * 服务详情
     */
    private ServiceDetail mServiceDetail;

    /**
     * 默认服务包剩余使用时间
     */
    private boolean serviceExpired;

    /**
     * 默认服务包服务类型（服务ID）
     */
    private int serviceId;

    /**
     * 当前选择学校
     */
    private SchoolDetail mSchoolDetail;

    /**
     * 班级详情列表
     */
    private List<Clazz> mClazzs;

    /**
     * 当前选择班级
     */
    private Clazz mClazz;

    private Grade mGrade;
    private List<EpaperInfo> mBookDeskEpaperInfos;


    public static String MOBILE;

    public static EApplication getInstance() {
        if (null == instance) {
            syn();
        }
        return instance;
    }

    public static synchronized void syn() {
        if (null == instance) {
            instance = new EApplication();
        }
    }

    public boolean isServiceExpired() {
        return serviceExpired;
    }

    public int getServiceId() {
        return serviceId;
    }

    public boolean isHasGotToken() {
        return hasGotToken;
    }

    public String getHasGotTokenMessage() {
        return hasGotTokenMessage;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        //内存泄漏相关
//        enabledStrictMode();
        setCrashReportListener(crashReportListener);
        File targetFile = ESystem.getCacheAddressFile(this);
        if (!targetFile.exists()) {
            FileUtil.copyFile(this, Constants.ADDRESS_DB, targetFile);
        }
    }


    @Override
    protected void init() {
        super.init();
        updatePassword();
        EpaperSys.setContext(getApplicationContext());
        ALiYunManager.getInstance().setContext(this);
        FeedbackUtil.getInstance().setContext(this);
        FeedbackUtil.getIPProvider(this);
        DownLoadDB.setContext(this);
        StudyRecordDB.setContext(this);
        Fresco.initialize(this);


        initNetAction();
        FileDownloader.setupOnApplicationOnCreate(this);
        FileDownloader.disableAvoidDropFrame();
        AppFrontBackHelper helper = new AppFrontBackHelper();
        helper.register(EApplication.this, new AppFrontBackHelper.OnAppStatusListener() {
            @Override
            public void onFront() {
                Log.e(TAG, "onFront: ");
                sendBroadcast(new Intent(IntentFlag.INTENT_FLAG_APP_ON_FRONT));
                if (BaseApplication.getInstance().isEyeGuardModeOpen) {
                    EventBus.getDefault().post(new CheckFloatPermissionBean(true));
                }
            }

            @Override
            public void onBack() {
                EyeGuardModeView.showEyeGuard(false);
            }
        });

        ESystem.getInstance().setContext(this);
        EpaperDao.getInstance().setContext(this);
        BaseDownLoad.getInstance().setContext(this);
        DownLoad.getInstance().setContext(this);
    }

    /**
     * 升级存取密码为密文
     */
    private void updatePassword() {
        try {
            boolean isUpdatepassword = CWSys.getSharedBoolean("updatepassword", false);
            if (!isUpdatepassword) {
                SerializableManager.getInstance().deSerialize(SerializableManager.SerializeKey.SHARE_KEY_USER_ACCOUNT_LIST,
                        new BaseCallBack() {
                            @Override
                            public void success(Object data) {

                                List<UserAccountInfo> userAccountList;
                                userAccountList = (ArrayList<UserAccountInfo>) data;

                                for (int i = 0; i < userAccountList.size(); i++) {
                                    userAccountList.get(i).setUserPwd(AESCBCUtil.encrypt(userAccountList.get(i).getUserPwd(), AESCBCUtil.AESCBC_HEX));
                                }
                                SerializableManager.getInstance().serialize(
                                        SerializableManager.SerializeKey.SHARE_KEY_USER_ACCOUNT_LIST,
                                        (Serializable) userAccountList, false);
                                CWSys.setSharedBoolean("updatepassword", true);
                            }

                            @Override
                            public void failed(int errorCode, Object data) {
                                CWSys.setSharedBoolean("updatepassword", true);
                            }

                            @Override
                            public void failed(Object data) {
                                CWSys.setSharedBoolean("updatepassword", true);
                            }
                        }, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        //sqlite 框架 关闭
    }

    /**
     * 初始化网络请求Action
     */
    protected void initNetAction() {
        HttpRequest.setVerifyInfoListener(new BaseRequest.VerifyInfoListener() {
            @Override
            public BaseRequest.VerifyInfo getVerifyInfo() {
                BaseRequest.VerifyInfo verifyInfo = null;

                try {
                    verifyInfo = (BaseRequest.VerifyInfo) CWSys.getSharedSerializable(
                            BaseConstants.SHARE_KEY_VERITIFY_INFO);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return verifyInfo;
            }
        });
        HttpRequest.registAction(StatUtils.MAction.class.getName(),
                new StatUtils.MAction());
        HttpRequest.registAction(MeAction.class.getName(), new MeAction());
        HttpRequest.registAction(EpaperAction.class.getName(),
                new EpaperAction());
        HttpRequest.registAction(ScanAction.class.getName(), new ScanAction());
        HttpRequest.registAction(MeAction.class.getName(), new MeAction());
        HttpRequest.registAction(LSAction.class.getName(), new LSAction());
        HttpRequest.registAction(MsgAction.class.getName(), new MsgAction());
        HttpRequest.registAction(CordvaAction.class.getName(), new CordvaAction());
        HttpRequest.registAction(BookstoreAction.class.getName(), new BookstoreAction());
        HttpRequest.registAction(WorkBookAction.class.getName(), new WorkBookAction());
        HttpRequest.registAction(DictationAction.class.getName(), new DictationAction());
        HttpRequest.registAction(WordAction.class.getName(), new WordAction());
    }

    /**
     * 获取服务详情列表
     *
     * @return 服务详情列表
     */
    public List<ServiceDetail> getServiceDetails() {
        if (mServiceDetails == null) {
            try {
                mServiceDetails = (List<ServiceDetail>) CWSys
                        .getSharedSerializable(
                                SerializableManager.SerializeKey.SHARE_KEY_SERVICE_DETAIL_LIST
                                        + SerializableManager.getInstance()
                                        .getUserId(true));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mServiceDetails;
    }

    /**
     * 设置服务详情列表
     *
     * @param serviceDetails 服务详情列表
     */
    public void setServiceDetails(List<ServiceDetail> serviceDetails) {
        this.mServiceDetails = serviceDetails;
        if (null != serviceDetails && serviceDetails.size() > 0) {
            ServiceDetail mServiceDetail = serviceDetails.get(0);
            if (mServiceDetail.getSurplusData() > 0) {
                this.serviceId = mServiceDetail.getServiceType();
                this.serviceExpired = true;
            } else {
                this.serviceId = mServiceDetail.getServiceType();
                this.serviceExpired = false;
            }
        } else {
            this.serviceId = 0;
            this.serviceExpired = false;
        }
    }

    public List<EpaperInfo> getBookDeskEpaperInfos() {
        if (mBookDeskEpaperInfos == null) {
            return null;
        }
        return mBookDeskEpaperInfos;
    }


    public void setBookDeskEpaperInfos(List<EpaperInfo> epaperInfos) {
        this.mBookDeskEpaperInfos = epaperInfos;
    }


    /**
     * 获取服务详情
     *
     * @return 服务详情
     */
    public ServiceDetail getServiceDetail() {
        if (mServiceDetail == null) {
            try {
                mServiceDetail = (ServiceDetail) CWSys.getSharedSerializable(SerializableManager.SerializeKey.SHARE_KEY_SERVICE_DETAIL + SerializableManager.getInstance().getUserId(true));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        StatUtils.brand = mServiceDetail == null ? 0
                : mServiceDetail.getServiceType();
        return mServiceDetail;
    }

    /**
     * 设置服务详情
     *
     * @param serviceDetail 服务详情
     */
    public void setServiceDetail(ServiceDetail serviceDetail) {

        this.mServiceDetail = serviceDetail;
        StatUtils.brand = mServiceDetail == null ? 0
                : mServiceDetail.getServiceType();
    }

    /**
     * 获取学校详情
     *
     * @return 学校详情
     */
    public SchoolDetail getSchoolDetail() {
        if (this.mSchoolDetail == null) {
            try {

                this.mSchoolDetail = (SchoolDetail) CWSys.getSharedSerializable(SerializableManager.SerializeKey.SHARE_KEY_CHOOSE_SCHOOL + SerializableManager.getInstance().getUserId(true));

            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        StatUtils.schoolId = mSchoolDetail == null ? 0
                : mSchoolDetail.getSchoolId();
        return mSchoolDetail;
    }

    /**
     * 设置默认学校详情
     *
     * @param schoolDetail 学校详情
     */
    public void setSchoolDetail(SchoolDetail schoolDetail) {
        mSchoolDetail = schoolDetail;
        StatUtils.schoolId = mSchoolDetail == null ? 0 : mSchoolDetail.getSchoolId();
    }

    /**
     * 设置班级列表
     *
     * @param clazzs
     */
    public void setClazzs(List<Clazz> clazzs) {
        this.mClazzs = clazzs;
    }

    /**
     * 获取班级列表
     *
     * @return 班级列表
     */
    public List<Clazz> getClazzs() {
        if (this.mClazzs == null) {
            try {
                this.mClazzs = (List<Clazz>) CWSys.getSharedSerializable(
                        SerializableManager.SerializeKey.SHARE_KEY_CLASS_LIST
                                + SerializableManager.getInstance()
                                .getUserId(true));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mClazzs;
    }

    /**
     * 获取班级详情
     *
     * @return 班级详情
     */
    public Clazz getClazz() {
        if (this.mClazz == null) {
            try {
                this.mClazz = (Clazz) CWSys.getSharedSerializable(
                        SerializableManager.SerializeKey.SHARE_KEY_CLASS_DEFAULT
                                + SerializableManager.getInstance()
                                .getUserId(true));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mClazz;
    }

    /**
     * 设置班级详情
     *
     * @param clazz 班级详情
     */
    public void setClazz(Clazz clazz) {
        mClazz = clazz;
    }

    /**
     * 拷贝asset目录下文件到sd卡上
     *
     * @param srcfilename 文件名
     * @param file        文件路径
     * @return 复制文件
     */
    public static boolean copyFile(Context context, String srcfilename, File file) {
        FileOutputStream fos = null;
        try {
            final int bufferSize = 1024;
            AssetManager am = context.getResources().getAssets();
            InputStream is = am.open(srcfilename);
            fos = new FileOutputStream(file);
            byte[] buffer = new byte[bufferSize];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String getProcessName(Context cxt, int pid) {
        ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if (runningApps != null) {
            for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
                if (procInfo.pid == pid) {
                    return procInfo.processName;
                }
            }
        }
        return null;
    }

    public void setGrade(Grade grade) {
        this.mGrade = grade;
        SerializableManager.getInstance().serialize(SerializableManager.SerializeKey.SHARE_KEY_GRADE_ID, mGrade);
    }

    public Grade getGrade() {

        if (mGrade == null) {
            Log.d(TAG, "#########getGrade null==grade##########");
            try {

                Log.d(TAG, "#########getGrade null==grade##########" + SerializableManager.SerializeKey.SHARE_KEY_GRADE_ID + SerializableManager.getInstance().getUserId(true));
                mGrade = (Grade) CWSys.getSharedSerializable(SerializableManager.SerializeKey.SHARE_KEY_GRADE_ID + SerializableManager.getInstance().getUserId(true));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (null == mGrade) {
                mGrade = new Grade();
                mGrade.setGradeId(0);
                mGrade.setGradeName("range_all");
            }
        } else {
            Log.d(TAG, "#########getGrade null!=grade##########");
        }
        return mGrade;
    }

    private void enabledStrictMode() {
        if (SDK_INT >= GINGERBREAD) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() //
                    .detectAll() //
                    .penaltyLog() //
                    .penaltyDeath() //
                    .build());
        }
    }

    CWCrashHandler.CrashReportListener crashReportListener = new CWCrashHandler.CrashReportListener() {
        @Override
        public void onCrashReport(String crashInfo) {
            Log.d("CWCrashHandler", "#####onCrashReport########" + crashInfo);
            FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_CRASH_TRACE_INFO, crashInfo, "崩溃堆栈信息");
        }
    };

    /**
     * 进入主应用才能执行
     */
    public void initAppData() {
        super.initAppData();
        //开启重试上传失败音频文件的服务
        UploadeFailService.startService();
        Stetho.initializeWithDefaults(this);
        EConstants.getHtmlPath();
        // 请选择您的初始化方式
        initAccessTokenLicenseFile();
    }

    @Override
    public Resources getResources() {//还原字体大小
        Resources res = super.getResources();
        Configuration configuration = res.getConfiguration();
        mFontSizeScale = getSharedInt("xixi:fontSizeScale", 1);
        configuration.fontScale = (float) (0.875 + 0.125 * mFontSizeScale);
        res.updateConfiguration(configuration, res.getDisplayMetrics());
        return res;
    }

    public SharedPreferences getSharedPreferences(String spName) {
        SharedPreferences sp;
        if (spName != null) {
            sp = getSharedPreferences(spName, 0);
        } else {
            sp = PreferenceManager.getDefaultSharedPreferences(this);
        }

        return sp;
    }


    public void setSharedBoolean(String key, boolean value) {
        SharedPreferences.Editor editor = getSharedPreferences((String) null).edit();
        editor.putBoolean(key, value);
        editor.commit();
    }


    public int getSharedInt(String key, int defValue) {
        return getSharedPreferences((String) null).getInt(key, defValue);
    }

    /**
     * 自定义license的文件路径和文件名称，以license文件方式初始化
     */
    private void initAccessTokenLicenseFile() {
        OCR.getInstance(getApplicationContext()).initAccessToken(new OnResultListener<AccessToken>() {
            @Override
            public void onResult(AccessToken accessToken) {
                String token = accessToken.getAccessToken();
                hasGotToken = true;
            }

            @Override
            public void onError(OCRError error) {
                error.printStackTrace();
                hasGotTokenMessage = error.getMessage();
            }
        }, "aip-ocr.license", getApplicationContext());
    }
}
